<!-- 发送框组件 -->
<script setup lang="ts">
declare const window: Window & typeof globalThis;
import { ref, watch } from 'vue';
import { Link2 } from 'lucide-vue-next';
import {
  ArrowUp,
  Atom,
  CirclePause,
  Globe,
  ImageUp,
  Paperclip,
  Plus,
} from 'lucide-vue-next';

import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger
} from '@/components/ui/tooltip';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuTrigger
} from '@/components/ui/dropdown-menu';
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'

// 1. 导入路由
import { useRouter } from 'vue-router';
const router = useRouter();

// 2. DOCX 解析
// @ts-ignore
import mammoth from 'mammoth';

// 3. PDF 解析核心：内联 Worker + 合法 blob URL（彻底解决所有问题）
// @ts-ignore：忽略类型声明缺失
import * as pdfjsLib from 'pdfjs-dist';
// 导入 PDF.js Worker 源码（注意：这里不加 ?worker，直接导入源码文本）
import pdfWorkerSrc from 'pdfjs-dist/legacy/build/pdf.worker.mjs?raw';

// 🔴 核心修复：创建合法的 Worker blob URL
// 步骤1：将 Worker 源码转为 blob 对象
const workerBlob = new Blob([pdfWorkerSrc], { type: 'application/javascript' });
// 步骤2：创建合法的 blob URL（浏览器可正常解析）
const workerBlobUrl = URL.createObjectURL(workerBlob);
// 步骤3：配置 PDF.js 使用合法的 blob URL 作为 workerSrc（无 fake worker 问题）
pdfjsLib.GlobalWorkerOptions.workerSrc = workerBlobUrl;

// 防止内存泄漏：组件卸载时释放 blob URL
import { onUnmounted } from 'vue';
onUnmounted(() => {
  URL.revokeObjectURL(workerBlobUrl);
});

const model = defineModel<{
  value: string
}>()

const props = defineProps<{
  loading: boolean
}>();

const emits = defineEmits<{
  onSubmit: [message: string, openReasoning: boolean, openSearch: boolean],
  onCancel:[],
}>();

const input = ref<string>(model.value?.value || '');
const openReasoning = ref(false);
const openSearch = ref(false);
const fileInputRef = ref<HTMLInputElement | null>(null);
const isFileLoading = ref(false);

// 监听模型变化
watch(
  () => model.value,
  (newValue) => {
    input.value = newValue?.value || '';
  }
);

// 工具方法
const toggleReasoning = () => {
  openReasoning.value = !openReasoning.value;
};
const toggleSearch = () => {
  openSearch.value = !openSearch.value;
};
const handleEnter = () => handleSubmit();
const handleSubmit = () => {
  emits('onSubmit', input.value, openReasoning.value, openSearch.value);
  input.value = '';
};
const handleCancel = () => emits('onCancel');
const handleUploadDoc = () => fileInputRef.value?.click();

// DOCX 解析逻辑
const parseDocxContent = async (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onload = async (event) => {
      try {
        const arrayBuffer = event.target?.result as ArrayBuffer;
        // @ts-ignore
        const result = await mammoth.extractRawText({ arrayBuffer });
        const cleanedContent = (result.value || '').trim().replace(/\s+/g, ' ').replace(/\n+/g, '\n');
        resolve(cleanedContent);
      } catch (err) {
        reject(new Error('DOCX 解析失败：' + (err as Error).message));
      }
    };
    reader.onerror = () => reject(new Error('DOCX 文件读取失败'));
  });
};

// PDF 解析逻辑（最终终极稳定版）
const parsePdfContent = async (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsArrayBuffer(file); // 必须用 ArrayBuffer 读取

    reader.onload = async (event) => {
      try {
        const arrayBuffer = event.target?.result as ArrayBuffer;
        // 创建 PDF 加载任务（使用合法 blob URL，无 fake worker 问题）
        const loadingTask = pdfjsLib.getDocument({
          data: arrayBuffer,
          cMapPacked: true,
          // 中文映射表：国内 CDN 稳定加载
          cMapUrl: 'https://cdn.bytedance.com/pdf.js/5.4.394/cmaps/',
          standardFontDataUrl: 'https://cdn.bytedance.com/pdf.js/5.4.394/standard_fonts/',
          verbosity: 0, // 关闭冗余日志
        });

        // 获取文档实例（关键：等待 promise 完成）
        const pdfDoc = await loadingTask.promise;
        console.log('PDF 加载成功：', pdfDoc.numPages, '页');

        // 提取所有页面文本
        let textContent = '';
        for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {
          const page = await pdfDoc.getPage(pageNum);
          const content = await page.getTextContent();

          // 过滤有效文本（排除无 str 属性的项）
          const pageText = content.items
            .filter((item: any) => 'str' in item)
            .map((item: any) => item.str)
            .join(' ');

          textContent += `${pageText}\n`; // 仅保留页面文本，去掉「第 X 页」前缀
        }

        // 处理空文本情况
        if (!textContent.trim()) {
          reject(new Error('PDF 无有效文本（可能是图片扫描件、加密文件或无文本层）'));
          return;
        }

        const cleanedContent = textContent.trim().replace(/\s+/g, ' ').replace(/\n+/g, '\n');
        resolve(cleanedContent);
      } catch (err) {
        const errorMsg = (err as Error).message || '未知错误';
        reject(new Error(`PDF 解析失败：${errorMsg}`));
      }
    };

    reader.onerror = () => reject(new Error('PDF 文件读取失败（文件损坏或格式不支持）'));
  });
};

// 统一文件处理逻辑
const handleFileChange = async (e: Event) => {
  const target = e.target as HTMLInputElement;
  const file = target.files?.[0];
  if (!file) return;

  const fileExtension = (file.name.split('.').pop()?.toLowerCase()) || '';
  const allowedExtensions = ['txt', 'docx', 'pdf'];

  // 格式校验
  if (!allowedExtensions.includes(fileExtension)) {
    alert(`请选择 ${allowedExtensions.join('/')} 格式的文件`);
    target.value = '';
    return;
  }

  // 大小限制
  const maxSize = fileExtension === 'pdf' ? 10 * 1024 * 1024 : 5 * 1024 * 1024;
  if (file.size > maxSize) {
    alert(`${fileExtension.toUpperCase()} 文件大小不能超过 ${maxSize / 1024 / 1024}MB`);
    target.value = '';
    return;
  }

  isFileLoading.value = true;
  let fileContent = '';

  try {
    switch (fileExtension) {
      case 'txt':
        fileContent = await new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.readAsText(file, 'utf-8');
          reader.onload = (event) => resolve((event.target?.result as string || '').trim());
          reader.onerror = () => reject(new Error('TXT 读取失败'));
        });
        break;
      case 'docx':
        fileContent = await parseDocxContent(file);
        break;
      case 'pdf':
        fileContent = await parsePdfContent(file);
        break;
    }

    // 🔴 核心修改：仅追加纯文件内容（无任何前缀信息）
    // 若输入框已有内容，先加 1 个换行分隔，避免粘连
    if (input.value.trim()) {
      input.value += `\n上传文件：\n${fileContent}`;
    } else {
      input.value = `上传文件：\n${fileContent}`; // 输入框为空时直接赋值，不额外加换行
    }

  } catch (err) {
    // 显示具体错误，帮助排查
    alert((err as Error).message || '文件处理失败，请重试');
    console.error('文件处理失败详情：', err);
  } finally {
    isFileLoading.value = false;
    target.value = ''; // 重置选择框
  }
};
</script>

<template>
  <div class="max-w-2xl w-full mx-auto fixed bottom-7 bg-background rounded-2xl
             outline-1 focus-within:outline-2 -outline-offset-1 focus-within:-outline-offset-2
             outline-muted-foreground/50 focus-within:outline-primary"
  >
    <Textarea
      v-model="input"
      class="max-h-[300px] min-h-[80px] w-full border-none shadow-none resize-none focus-visible:ring-transparent mt-1 p-3 overflow-y-auto"
      placeholder="请输入你的问题..."
      @keydown.enter.prevent="handleEnter"
    ></Textarea>

    <div class="flex items-center space-x-2 py-2 px-4">
      <DropdownMenu>
        <DropdownMenuTrigger as-child>
          <Button
            class="h-7 w-7 rounded-full cursor-pointer"
            variant="outline"
            :disabled="isFileLoading"
          >
            <Plus />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent
          class="w-(--radix-dropdown-menu-trigger-width) min-w-30 rounded-lg"
          side="top"
          align="end"
          :side-offset="10"
          :align-offset="-50"
        >
          <DropdownMenuGroup>
            <DropdownMenuItem @click="handleUploadDoc" :disabled="isFileLoading">
              <Paperclip />
              上传文档
              <span v-if="isFileLoading" class="ml-2 text-xs text-muted-foreground">读取中...</span>
            </DropdownMenuItem>
            <DropdownMenuItem>
              <ImageUp />
              上图片
            </DropdownMenuItem>
          </DropdownMenuGroup>
        </DropdownMenuContent>
      </DropdownMenu>

      <input
        ref="fileInputRef"
        type="file"
        style="display: none"
        accept=".txt,.docx,.pdf"
        @change="handleFileChange"
      />

      <TooltipProvider>
        <Tooltip>
          <TooltipTrigger as-child>
            <Button
              class="h-7 cursor-pointer"
              :class="{
                'bg-primary/30 text-primary hover:bg-primary/30 hover:text-primary': openReasoning
              }"
              variant="outline"
              @click="toggleReasoning"
            >
              <Atom />
              <span class="text-sm">深度思考</span>
            </Button>
          </TooltipTrigger>
          <TooltipContent v-if="!openReasoning" side="bottom">
            <span class="text-primary-foreground">深度思考</span>
          </TooltipContent>
        </Tooltip>
      </TooltipProvider>

      <Tooltip>
        <TooltipTrigger as-child>
          <Button
            class="h-7 cursor-pointer"
            :class="{
              'bg-primary/30 text-primary hover:bg-primary/30 hover:text-primary': openSearch
            }"
            variant="outline"
            @click="toggleSearch"
          >
            <Globe />
            <span>搜索</span>
          </Button>
        </TooltipTrigger>
        <TooltipContent v-if="!openSearch" side="right">
          <span class="text-primary-foreground">联网搜索</span>
        </TooltipContent>
      </Tooltip>

      <Tooltip>
        <TooltipTrigger as-child>
          <Button
            class="h-7 cursor-pointer"
            variant="outline"
            @click="router.push('/redirect-to-analysis')"
          >
            <Link2 class="mr-1" />
            <span>总结b站视频</span>
          </Button>
        </TooltipTrigger>
        <TooltipContent side="right">
          <span class="text-primary-foreground">打开链接总结bilibili视频内容</span>
        </TooltipContent>
      </Tooltip>

      <template v-if="!loading">
        <Tooltip>
          <TooltipTrigger as-child>
            <Button
              class="h-7 w-7 rounded-full cursor-pointer active:bg-primary ml-auto"
              size="icon"
              type="submit"
              :disabled="!input && !loading"
              @click="handleSubmit"
            >
              <ArrowUp />
            </Button>
          </TooltipTrigger>
          <TooltipContent>
            <span class="text-primary-foreground">发送</span>
          </TooltipContent>
        </Tooltip>
      </template>
      <template v-else>
        <Tooltip>
          <TooltipTrigger as-child>
            <Button
              class="h-7 w-7 rounded-full cursor-pointer active:bg-primary ml-auto"
              size="icon"
              type="submit"
              @click="handleCancel"
            >
              <CirclePause />
            </Button>
          </TooltipTrigger>
          <TooltipContent>
            <span class="text-primary-foreground">停止</span>
          </TooltipContent>
        </Tooltip>
      </template>
    </div>
  </div>
</template>

<style scoped>
</style>